package de.tum.in.eist.im.client;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;

import de.tum.in.eist.im.client.domain.*;

/**
 *  The Event Handler Class that fetches AbstractEvents from the server and works on them.
 * @author Stephan
 *
 */
public class Actualizer extends Timer{
	private final ChatServiceAsync chatService = GWT.create(ChatService.class);
	private final EIST_IM client;
	private long lastTimeStamp;
	public Actualizer (EIST_IM c){
		client = c;
		lastTimeStamp = 0;
	}
	@Override
	public void run(){
			actualize();
	}
	/**
	 * tries to get a AbtractEvent from the server for the user to work on it.
	 * Waits if no AbstractEvent is available.
	 * Recursive.
	 */
	private void actualize() {
		chatService.getEventsBlocking(client.getUser(), new AsyncCallback<List<AbstractEvent>> (){

			@Override
			public void onFailure(Throwable caught) {
				client.setErrorLabelText("failed to actualize");
			}

			@Override
			public void onSuccess(List<AbstractEvent> result) {
				while(!result.isEmpty()){
					workEvent(result.remove(0));
				}
				actualize();
			}
			
		});
	}
	/**
	 * checks the typ of events and works on them
	 */
	private void workEvent(AbstractEvent event) {
		if(event instanceof MessageEvent){
			this.getHist();
		}
		if(event instanceof UserEvent){
			this.workUserEvent((UserEvent)event);
		}
	}
	private void workUserEvent(UserEvent e){
		if (e.isLogin()) {
			//login
			if(!client.getUser().equals(e.getUser()))
				client.setLoggedInUser(e.getUser());			
		} else {
			//logout
			client.removeLoggedInUser(e.getUser());
			
		}
	}
	/**
	 * fetches the Messages from the server
	 */
	public void getHist(){
		chatService.getNewMessages(lastTimeStamp, new AsyncCallback<NewMessagesChunk>(){
			@Override
			public void onFailure(Throwable chaught){
				client.setErrorLabelText("failed to fetch messages");
			}
		
			@Override
			public void onSuccess(NewMessagesChunk result){
				long time = result.getTimestamp();
				lastTimeStamp = time;
				client.setMessages(result.getMessages(), time);
			}
		});
	}
	/**
	 * gets logged in users
	 */
	public void getLoggedInUsers (){
		AsyncCallback<List<User>> callback= new AsyncCallback<List<User>>(){

			@Override
			public void onFailure(Throwable caught) {
				client.setErrorLabelText("failed to get logged in users");
				
			}

			@Override
			public void onSuccess(List<User> result) {
				// TODO Auto-generated method stub
				client.setLoggedInUsers(result);
			}
			
		};
		this.chatService.getLoggedInUsers(callback);
	}
}
